function [MinVal,min_individual,trace]=GA(NIND,MAXGEN,fobj,PTime,dim)
%% 数据,每个工件的每道工序时间
%% 基本参数

GGAP=0.9;        %代沟
XOVR=0.85;       %交叉率
MUTR=0.02;       %变异率
gen=0;           %代计数器
%PNumber 工件个数 MNumber  工序个数
[PNumber,MNumber]=size(PTime);  
trace=zeros(1, MAXGEN);      %%%%寻优结果的初始值，每代适应度函数值？？？？
 

% 编码
Chrom=rand(NIND,dim); %随机产生0到1的随机数，长度是工件*工序
for i=1:dim
    FieldDR(1,i)=0;
    FieldDR(2,i)=3;
end

%计算目标函数值
for i=1:NIND
[TCost]=fobj(PTime,Chrom(i,:));%%%%%调用子函数计算工序的完成时间，可以与子函数返回值名字一样吗？？？？？？？
ObjV(i,1)=TCost;
end

%% 循环寻找
while gen<MAXGEN
    
    %分配适应度值（ ranking是按照个体目标函数值ObjV由小到大的顺序对其排序，并返回包含个体适应度值FitnV的列向量）
    FitnV=ranking(ObjV);  
    %选择操作
    SelCh=select('rws', Chrom, FitnV, GGAP);  %rws表示轮盘选择函数     
    %交叉操作
    SelCh=recombin('xovdp', SelCh, XOVR);  % xovdp函数表示两点交叉， XOVR表示概率    
    %变异操作
    SelCh=mutate('mutbga', SelCh, FieldDR, [MUTR 0.5]); % mutbga表示恒定步长的变异，变异率是MUTR，步长是0.5          
    
    %计算目标适应度值
    [m,n]=size(SelCh);
    for i=1:m
       [TCost]=fobj(PTime,SelCh(i,:));  %%%%%调用子函数计算工序的完成时间，输入值和返回值必须与子函数一一对应吗？？？
        ObjVSel(i,1)=TCost;
   
    end
    
    %重新插入新种群
    [Chrom,ObjV] =reins(Chrom, SelCh,1, [1 1], ObjV, ObjVSel);  %第二个1表示基于适应度用子代代替父代， ObjV父代中个体的目标值，ObjVSel子代中个体的目标值
    %代计数器增加
    gen=gen+1;       
    
    %保存最优值
    [trace(1, gen),index]=min(ObjV);       
    % trace(2, gen)=mean(ObjV);
    temp_individual = Chrom(index,:);

 
    
    % 记录最佳值
    if gen==1
        MinVal=min(ObjV);%最小适应度值
        min_individual = temp_individual;
    end
    
 
    if MinVal> trace(1,gen)
        MinVal=trace(1,gen);
        min_individual = temp_individual;
    end
    
end

end

